//
//  HttpPlatformConnect.m
//  XTCloud
//
//  Created by QA on 2018/1/10.
//  Copyright © 2018年 ShangHai HaoLei Software Technology Co., Ltd. All rights reserved.
//

#import "HttpPlatformConnect.h"
#import "AFNetworkActivityIndicatorManager.h"
#import "AESCrypt.h"
#import "NSDictionary+DataFormat.h"

@interface HttpPlatformConnect ()

@property (nonatomic, strong) AFHTTPSessionManager *httpSessionManager;
@property (nonatomic, assign) BOOL hasCertificate;  ///< 有无证书，default is NO

@end

@implementation HttpPlatformConnect

static HttpPlatformConnect *zdAFHelper = nil;
+ (instancetype)shareInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        zdAFHelper = [[HttpPlatformConnect alloc] init];
        [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
    });
    
    return zdAFHelper;
}

#pragma mark - Property

- (AFHTTPSessionManager *)httpSessionManager
{
    if (!_httpSessionManager) {
        _httpSessionManager = [AFHTTPSessionManager manager];
        _httpSessionManager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/plain", @"text/html", @"application/rss+xml", @"application/soap+xml", @"application/xml", nil];
        _httpSessionManager.requestSerializer.timeoutInterval = 10;
        self.hasCertificate = NO;
        
        if (self.hasCertificate) {
            ///有cer证书时AF会自动从bundle中寻找并加载cer格式的证书
            AFSecurityPolicy *securityPolicy = ({
                AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];
                securityPolicy.allowInvalidCertificates = YES;
                securityPolicy;
            });
            _httpSessionManager.securityPolicy = securityPolicy;
        }
        else {
            ///无cer证书的情况,忽略证书,实现Https请求
            AFSecurityPolicy *securityPolicy = ({
                AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
                securityPolicy.allowInvalidCertificates = YES;
                securityPolicy.validatesDomainName = NO;
                securityPolicy;
            });
            _httpSessionManager.securityPolicy = securityPolicy;
        }
    }
    return _httpSessionManager;
}

#pragma mark - Operations

- (void)cancelAllOperations
{
    [[HttpPlatformConnect shareInstance].httpSessionManager.operationQueue cancelAllOperations];
}


#pragma mark - 平台接口
//平台接口
- (NSURLSessionDataTask *)requestWithParams:(HttpPlatformInputRequest*)httpInputParams
                                    success:(PlatformSuccessHandle)successBlock
                                    failure:(PlatformFailureHandle)failureBlock
{
    //默认POST请求
    PlatformHttpMethod httpMethod = Platform_HttpMethod_POST;
    
    // 1.处理参数及URL
    id URL = PlatformHttpURL;
    id params = [httpInputParams getParame];
    NSLog(@"参数：%@",params);
    
    // 2.初始化请求管理对象，设置规则
    //AFHTTPRequestSerializer            二进制格式
    //AFJSONRequestSerializer            JSON,已改动源码，支持文本
    //AFPropertyListRequestSerializer    PList(是一种特殊的XML,解析起来相对容易)
    self.httpSessionManager.requestSerializer = [AFHTTPRequestSerializer serializer];
    
    // 设置返回格式
    //AFHTTPResponseSerializer           二进制格式
    //AFJSONResponseSerializer           JSON
    //AFXMLParserResponseSerializer      XML,只能返回XMLParser,还需要自己通过代理方法解析
    //AFXMLDocumentResponseSerializer (Mac OS X)
    //AFPropertyListResponseSerializer   PList
    //AFImageResponseSerializer          Image
    //AFCompoundResponseSerializer       组合
    self.httpSessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
    
    // 3.发送请求
    NSURLSessionDataTask *sessionTask = nil;
    __weak __typeof(&*self) ws = self;
    switch (httpMethod) {
        case Platform_HttpMethod_GET: {
            sessionTask = [self.httpSessionManager GET:URL parameters:params progress:^(NSProgress * _Nonnull downloadProgress) {
                //TODO:下载进度
            } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                [ws customDecodeData:responseObject success:successBlock failure:failureBlock];
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                if (failureBlock) {
                    failureBlock(error);
                }
            }];
            break;
        }
            
        case Platform_HttpMethod_POST: {
            // 参数中不包含NSData类型
            sessionTask = [self.httpSessionManager POST:URL parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
                //TODO:上传进度
            } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                [ws customDecodeData:responseObject success:successBlock failure:failureBlock];
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                if (failureBlock) {
                    failureBlock(error);
                }
            }];
            break;
        }
            
        default: {
            break;
        }
    }
    
    return sessionTask;
}

//解析数据
- (void)customDecodeData:(id)data success:(PlatformSuccessHandle)successBlock failure:(PlatformFailureHandle)failureBlock
{
    @try {
        //解析服务器返回的加密数据
        NSString *decryptString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSData *decryptData= [decryptString dataUsingEncoding:NSUTF8StringEncoding];
        
        //解析服务器返回的数据
        NSError *error;
        id jsonObject = [NSJSONSerialization JSONObjectWithData:decryptData options:NSJSONReadingAllowFragments error:&error];
        if (error || ![jsonObject isKindOfClass:[NSDictionary class]]){
            NSLog(@"An error happened while deserializing the JSON data.");
            if (failureBlock) failureBlock(error);
            return;
        }
        
        NSDictionary *valueJson = jsonObject;
        NSInteger state = [valueJson objectFormatIntegerForKey:@"state"];
        id code = [valueJson objectFormatForKey:@"code"];
        id value = [valueJson objectFormatForKey:@"data"];
        NSString *message = [valueJson objectFormatStringForKey:@"message"];
        NSString *mLocalized = [NSString stringWithFormat:@"%@:%@", code, message];
        
        NSString *jsonString = [AESCrypt decrypt:value];//数据解密
        NSData *jsonData= [jsonString dataUsingEncoding:NSUTF8StringEncoding];
        if(!jsonData) {//数据解析出错
            NSDictionary *userInfo = [NSDictionary dictionaryWithObject:mLocalized forKey:NSLocalizedDescriptionKey];
            NSError *stateError = [NSError errorWithDomain:@"com.holui.http.state" code:state userInfo:userInfo];
            if (failureBlock) failureBlock(stateError);
            return;
        }
        
        //解析data数据
        id jsonArray = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:&error];
        if (!jsonArray || ![jsonArray isKindOfClass:[NSArray class]]){
            NSLog(@"An error happened while deserializing the JSON data.");
            if (failureBlock) failureBlock(error);
            return;
        }
        
        //服务器异常数据返回处理
        if(state > 0 && value) {
            HttpPlatformOutputResult *mResult = [[HttpPlatformOutputResult alloc] initWithObjectResult:jsonArray];
            if (successBlock) successBlock(mResult);
        } else {
            NSLog(@"%@",decryptString);
            NSDictionary *userInfo = [NSDictionary dictionaryWithObject:mLocalized forKey:NSLocalizedDescriptionKey];
            NSError *stateError = [NSError errorWithDomain:@"com.holui.http.state" code:state userInfo:userInfo];
            if (failureBlock) failureBlock(stateError);
        }
        
    } @catch (NSException *exception) {
        NSLog(@"HttpPlatformConnect解析异常：%@",exception);
        NSError *stateError = [NSError errorWithDomain:@"HttpPlatformConnect解析异常" code:2001 userInfo:exception.userInfo];
        if (failureBlock) failureBlock(stateError);
    }
}

@end
